Tous d'abord le type de données Tradln associé aux lignes récupérées du fichier texte en entrée.
data Tradln = Tradln { lnCode :: String -- Identifiant de la cellule (Automatique ou manuel)
, lnTradEn :: String -- Le mot en Anglais
, lnTradFr :: String -- Le mot en Français
, lnDom1 :: String -- Le domaine 1
, lnDom2 :: String -- Le domaine 2
, lnDom3 :: String -- Le domaine 3
, lnVersion :: Int -- Le numéro de version
, lnOk :: Bool -- Intégration de la ligne ou non
} deriving (Eq)
Ce type contient les champs associés à une ligne de données sous la forme de chaîne de caractère String pour les mots et les domaines, un entier Int pour le numéro de version et un booléen Bool pour l'intégration de la ligne.
Ensuite le type Traduction contenant un groupe (cellule) de traduction.
data Traduction = Traduction { code :: String -- Identifiant de la cellule (Automatique ou manuel)
, lang :: Lang -- La langue de la cellule
, tradEn :: [TradLaTeXEn] -- Une liste de traductions en Anglais
, tradFr :: [TradLaTeXFr] -- Une liste de traductions en Français
, dom1 :: String -- Le domaine 1
, dom2 :: String -- Le domaine 2
, dom3 :: String -- Le domaine 3
} deriving (Eq)
Ce type contient les champs de type String, de type spécial [TradLaTeXEn]
pour les traductions et de type Lang
pour la langue dans laquelle s'effectue la traduction. Ce type Lang
sert à définir la langue et peut valoir En
(Anglais) ou Fr
(Français):
data Lang = En | Fr deriving (Eq)
et enfin les types [TradLaTeXFr]
et [TradLaTeXEn]
qui serviront à l'exportation des commandes LaTeX plus loin:
data TradLaTeXEn = TradLaTeXEn (String) deriving (Eq)
data TradLaTeXFr = TradLaTeXFr (String) deriving (Eq)
Afin de filtrer les lignes de traduction, on utilise la fonction filter qui permet d'appliquer un critère à une liste et de retourner une liste qui vérifie ce critère. Pour définir ce critère, on peut utiliser plusieurs fonctionnalités qu'offre Haskell :
filtreOk lst = filter (\a -> (lnOk a) == True) lst
Avec Haskell le symbole \\
(backslash) avec ->
permet de déclarer ce type de fonction. La fonction déclarée ici prend un argument a et retourne True
si le code d'intégration est égal à True.
filtreOk lst = filter((==True) . lnOk) lst
Avec Haskell, le point à la même signification qu'en mathématiques. C'est l'opérateur de composition de fonctions.
Ces deux écritures fonctionnent aussi bien l'une que l'autre
La fonction filtreOk
permet de filtrer les lignes de la liste lst si lnOk
est vrai (True).
filtreOk :: [Tradln] -> [Tradln]
filtreOk lst = filter ((==True) . lnOk) lst
La fonction filtreVer
permet de filtrer les lignes de la liste lst dont le numéro de version est inférieur ou égale à ver
filtreVer :: Int -> [Tradln] -> [Tradln]
filtreVer ver lst = filter ((<=ver) . lnVersion) lst
Les fonctions suivantes permettent de filtrer les listes ayant respectivement le même mot anglais, le même mot français et le même code de regroupement.
filtreEn :: [Tradln] -> String -> [Tradln]
filtreEn lst mot = filter ((==mot) . lnTradEn) lst
filtreFr :: [Tradln] -> String -> [Tradln]
filtreFr lst mot = filter ((==mot) . lnTradFr) lst
filtreCode :: [Tradln] -> String -> [Tradln]
filtreCode lst code = filter ((==code) . lnCode) lst
La fonction filtreDom
permet de filtrer les lignes de la liste lst si l'un des domaines est égal à celui renseigné en paramètres. Pour effectuer le test logique, on pourrait créer une fonction spécifique du style :
test dom ln = dom == lnDom1 ln || dom == lnDom2 ln || dom == lnDom3 ln
et l'utiliser comme filtre de cette façon :
filtreDom lst dom = filter (test dom) lst
mais on peut aussi condenser l'écriture sur une ligne en utilisant une fonction anonyme.
filtreDom :: [Tradln] -> String -> [Tradln]
filtreDom lst dom = filter (\a -> dom == lnDom1 a || dom == lnDom2 a || dom == lnDom3 a) lst
Cette fonction prend comme argument a, une ligne de traduction, et la vérifie si le domaine 1 de a est égale à dom ou si le domaine 2 de a est égale à dom ou si le domaine 3 de a est égale à dom.
La fonction Haskell de base pour trier une liste est sort. Mais attention, cette fonction bien qu'elle puisse être utilisée sur des types contenant des champs va effectuer un tri sur tous les champs les uns après les autres (tri selon la version, puis tri selon les domaines, puis tri selon les mots, etc…). Or ce n'est pas ce que l'on veut ici. Il est nécessaire d'imposer le tri suivant un seul champ. Pour cela, il y a la fonction sortBy
(tri selon…). Pour l'utiliser, il faut lui fournir en premier argument une fonction effectuant la comparaison.
triEn :: [Tradln] -> [Tradln]
triEn lst = sortBy (on compare lnTradEn) lst
triFr :: [Tradln] -> [Tradln]
triFr lst = sortBy (on compare lnTradFr) lst